256 Farben

← Zurück zum Forum

Hallo in die Runde, ich wollte hier mal ein neues Thema aufmachen:

Theorie und Praxis - wie stelle ich 256 Farben beim A8 dar.

Theorie ist halbwegs klar. Man nimmt den GTIA Modus 9 und 11 - einer kann 16 Helligkeiten und der andere 16 Farbe. Mischt das via DL und DLI über PRIOR und schon kann man irgendwie die 256 Farben gleichzeitig darstellen. Jetzt nur noch die Frage, wie man das ganz konkret in Assembler baut??

Liebe Grüße Peter

AntwortZitat

Ich habe mal ein kleines Plasma (96*11, gespiegelt und auch noch jeweils 3 Zeilen je Grafikstufe hoch) in 256 Farben als Beispielcode in mads für Euch:

/*
256 colors in asm
08.09.2023 PPs
*/

; @com.wudsn.ide.asm.hardware=ATARI8BIT

;------------ sys definitions 
.enum @dmactl
  blank = %00
  narrow  = %01
  standard= %10
  wide  = %11
  missiles= %100
  players = %1000
  lineX1  = %10000
  lineX2  = %00000
  dma = %100000
.ende

.enum @gtictl
  prior0  = %0
  prior1  = %1
  prior2  = %10
  prior4  = %100
  prior8  = %1000
  ply5  = %10000  ; Fifth Player Enable
  mlc = %100000 ; Multiple Color Player Enable
  mode9 = %01000000
  mode10  = %10000000
  mode11  = %11000000
.ende

trig0 = $D010
trig1 = $D011
color0  = $D016
color1  = $D017
color2  = $D018
color3  = $D019
colbak  = $D01A
gtictl  = $D01B
consol  = $D01F

skctl = $D20F

dmactl  = $D400
wsync = $D40A
nmien = $D40E

setvbv  = $E45C
xitvbv  = $E462
sysvbv  = $E45f
coldst  = $E477
;------------ end of sys definitions

BEGIN equ $2000       ;address programm code starts
scr9  equ $8000       ;screen address -> gfx9 part
scr11 = scr9+11*48        ;screen address -> gfx11 part
pl9 = scr11+11*48       ;plasma buffer
pl11  = pl9+11*48       ;plasma buffer 2

;------------
  .zpvar  .byte rega,regx,regy    ;zp for DLI (stack usage is possible, too)
  .zpvar  .word copyfrom,copyto,copyfrom2,copyto2 ;zp for plasma
  .zpvar  .byte cont,m,m9,m11,my,test,test2   ;zp for plasma
;------------
  org BEGIN
;------------
  .proc ant
:7  .he 70
  .he 80 10
;---  6 lines altering gfx9 and gfx11
  .rept 3
  .he 4f
  .wo scr9
  .he 4f
  .wo scr11
  .endr
;---  and now for the rest, too
  .rept 3
  .he 4f
  .wo scr9+48
  .he 4f
  .wo scr11+48
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*2
  .he 4f
  .wo scr11+48*2
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*3
  .he 4f
  .wo scr11+48*3
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*4
  .he 4f
  .wo scr11+48*4
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*5
  .he 4f
  .wo scr11+48*5
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*6
  .he 4f
  .wo scr11+48*6
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*7
  .he 4f
  .wo scr11+48*7
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*8
  .he 4f
  .wo scr11+48*8
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*9
  .he 4f
  .wo scr11+48*9
  .endr
;---
  .rept 3
  .he 4f
  .wo scr9+48*10
  .he 4f
  .wo scr11+48*10
  .endr
;---
  .rept 3
  .he 4f
  .wo scr9+48*9
  .he 4f
  .wo scr11+48*9
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*8
  .he 4f
  .wo scr11+48*8
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*7
  .he 4f
  .wo scr11+48*7
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*6
  .he 4f
  .wo scr11+48*6
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*5
  .he 4f
  .wo scr11+48*5
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*4
  .he 4f
  .wo scr11+48*4
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*3
  .he 4f
  .wo scr11+48*3
  .endr
  .rept 3
  .he 4f
  .wo scr9+48*2
  .he 4f
  .wo scr11+48*2
  .endr
  .rept 3
  .he 4f
  .wo scr9+48
  .he 4f
  .wo scr11+48
  .endr
  .rept 3
  .he 4f
  .wo scr9
  .he 4f
  .wo scr11
  .endr
;--
  .he 41
  .wo ant
  .endp
;------------
  .proc main
  mva #0 559
  sta nmien

  mwa #ant 560
  lda #7      ;VBI
  ldx >vbi    ;wird
  ldy <vbi    ;jetzt
  jsr setvbv    ;initialisiert
  mva #$c0 nmien    ;DLI + VBI an
  mva #34 559

mainloop
  jsr plasma
;---  reduce on screen painting
  lda 20
@ cmp 20
  beq @-
;---
  jsr copy2screen
  jmp mainloop
  .endp
;------------
  .proc vbi
  mwa #dli 512
;---
  lda trig0
  beq @+
  lda trig1
  beq @+
  lda skctl
  and #$04
  beq @+
  lda consol
  and #1
  bne nixtun
@ jmp coldst  ;exit
nixtun
  jmp xitvbv
  .endp
;------------
  .proc dli
  sta rega
  stx regx

  sta wsync
  mva #$e colbak
  sta wsync
  lda #0
  sta colbak
  mva #@dmactl(wide|dma) dmactl
;---  gtia mode start
  ldx #62
lx  mva #@gtictl(mode9) gtictl
  sta wsync
  mva #@gtictl(mode11) gtictl
  mva #$4 colbak
  sta wsync
  mva #0 colbak
  dex
  bpl lx
  mva #@gtictl(mode9) gtictl
  sta wsync 
  mva #0 gtictl
;---  gtia mode end
  sta wsync
  mvx #$e colbak
  sta wsync
  sta colbak
  ldx regx
  lda rega
  rti
  .endp
;------------
  .proc copy2screen
  mwa #scr9 copyto  ;copyto1
  mwa #scr11 copyto2  ;copyto2
  mwa #pl9 copyfrom ;plasma gfx9
  mwa #pl11 copyfrom2 ;plasma gfx11

  ldx #10
lx  ldy #47
ly  lda (copyfrom),y  ;plasma gfx9
  sta (copyto),y    ;screen gfx9
  lda (copyfrom2),y ;plasma gfx11
  sta (copyto2),y   ;screen gfx11
  dey
  bpl ly
  adw copyto #48 copyto
  adw copyto2 #48 copyto2
  adw copyfrom2 #48 copyfrom2
  adw copyfrom #48 copyfrom
  dex
  bpl lx
  rts
  .endp
;------------
  .proc plasma
  mwa #sin_tab copyfrom
  mwa #pl9 copyto
  mwa #pl11 copyto2
  mva #0 cont
  ldy #10
l_y ldx #95
l_x sty test2
  txa
  tay
  lda (copyfrom),y
  add 20
  sta test
  ldy test2
  lda (copyfrom),y
  add test
  add 20
  tay
  lda colors11,y
  and #$f0  ;high
  sta m11
  lda colors9,y
  and #$f0
  sta m9
;---
  dex
  txa
  tay
  lda (copyfrom),y
  add 20
  sta test
  ldy test2
  lda (copyfrom),y
  add test
  add 20
  tay
  lda colors11,y
  and #$0f  ;low
  sta m
  sty my
  ldy #0
  lda m11
  eor m
  sta (copyto2),y
  ldy my
  lda colors9,y
  and #$0f
  sta m
  ldy #0
  lda m9
  eor m
  sta (copyto),y
;----
  inw copyto
  inw copyto2
  ldy test2
  dex
  jpl l_x
  inc cont
  dey
  jpl l_y
  rts
;----------
; color tables
colors11
  .rept 8
  .he 00 11 11 22 22 33 33 44 44 55 55 66 66 77 77 88
  .he 88 77 77 66 66 55 55 44 44 33 33 22 22 11 11 00
  .endr
;----------
colors9
  .rept 2
:8  .he 00  ;-> if black to white is not wanted change here to other than 00
:8  .he 11  ;-> 11 and ff is almost the same in PAL
:8  .he 22
:8  .he 33
:8  .he 44
:8  .he 55
:8  .he 66
:8  .he 77
:8  .he 88
:8  .he 99
:8  .he aa
:8  .he bb
:8  .he cc
:8  .he dd
:8  .he ee
:8  .he ff  ;-> 11 and ff is almost the same in PAL
  .endr
;----------
sin_tab
  dta b(sin(0,50,75,0,255))
  .endp
;------------
  run main

Natürlich ist nichts optimiert und man könnte auch die Grafik direkt hintereinander im Speicher haben, nicht in 2 Bereichen für die unterschiedlichen Grafikmodi, aber ich finde es so schöner, gerade wenn man eventuell später noch fine scrolling einbauen wollte. 256col.zip PS: gerade, weil die Farben im colors9 am Ende Schwarz bringen, habe ich wohl ein sta wsync zu viel drin und somit gfx9 und gfx11 vertauscht 😉 PSS: Ja, so ist es... colors 9 und 11 tauschen, im ant :6 .he 70, statt :7 .he 70 und danach dann .he f0 20 dann im DLI noch ldx #62 auch ldx #63 ändern und alles ist korrekt 😂 256col_korrektur.zip

Anhänge:

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

AntwortZitat

Lieben Dank... sieht toll aus! Komisch, daß ich den Code nicht über den Mac Emulator starten kann. Altirra geht ... Kannst du das auch erklären, was du da genau machst ?? 😉

AntwortZitat

Abewchselnd wird in der ant Prozedur jeweils für gfx 9 und gfx11 eine Zeile definiert (immer mit LMS, da ich ja für gfx9 und gfx11 eigene Bereiche nehme). Da ich das Plasma ja spiegele und jeweils 3*2 Zeilen je berechnetem Plasma Punkt in der Höhe nutze, ist immer das .rept 3 und .endr drin. Das spart ein wenig Schreibarbeit.

Im Main wird dann der VBI gesetzt, VBI & DLI angeknipst und auch die DL initialisiert. Dann gibt es noch den mainloop, in dem das Plasma berechnet wird und danach in den sichtbaren Bereich kopiert wird.

Der VBI setzt die DLI Adresse (besonders, wenn man mehrere DLIs verschachtelt ist das sehr sinnvoll - machen wir hier aber nicht) und man kann per Joystickknopf (an joy0 & 1), Tastaturdruck oder auch per START den Kaltstart auslösen.

copy2screen kopiert das berechnete Plasma in den sichtbaren Bereich.

Plasma berechnet das Plasma. Dazu gibt es die Sinustabelle und die beiden Farbtabellen (in der korrigierten Version sind die auch richtig). Auch die Zeit wird genutzt. (Ich sehe gerade, dass ich hier das cont nicht wirklich nutze. Das kann dann also auch komplett rausgenommen werden 😂 ) Damit das Plasma auch wirklich die 96 Punkte horizontal berechnet, habe ich dieses high und low drin.

Im DLI wird der Bildschirm an der richtigen Stelle auf volle Breite gestellt und dann im loop zwischen gfx9 und gfx11 umgeschaltet. Bei gfx9 sollte immer die Helligkeit (also colbak) auf 0 gesetzt werden, um alle Helligkeiten erreichen zu können. gfx11 sollte aber nicht so dunkel sein, sonst wirkt es nicht so richtig, daher wird hier die Helligkeit auf 4 gesetzt - es gehen aber auch andere Werte.

Ich hoffe das hilft ein wenig. Wenn das noch immer zu unklar ist, gerne weiter fragen 😉

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

AntwortZitat

Hier für die korrigierte Version ein paar Farbschemen:

Rot + Blau

colors11
  .rept 4
  .rept 4
:8  .he 22
  .endr
  .rept 4
:8  .he 88
  .endr
  .endr

Blau + Gelb

colors11
  .rept 4
  .rept 4
:8  .he 88
  .endr
  .rept 4
:8  .he ee
  .endr
  .endr

RGB (ein klein wenig zu groß, aber ich bin gerade faul 😀):

colors11
  .rept 4
  .rept 3
:8  .he 22
  .endr
  .rept 3
:8  .he aa
  .endr
  .rept 3
:8  .he 88
  .endr
  .endr

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

AntwortZitat

Noch eines für wirklich alle Farben:

colors9
  .rept 8
  .he 00 11 22 33 44 55 66 77 88 99 aa bb cc dd ee ff
  .he ff ee dd cc bb aa 99 88 77 66 55 44 33 22 11 00
  .endr
;----------
colors11
:16 .he 00  ;-> if black to white is not wanted change here to other than 00
:16 .he 11  ;-> 11 and ff is almost the same in PAL
:16 .he 22
:16 .he 33
:16 .he 44
:16 .he 55
:16 .he 66
:16 .he 77
:16 .he 88
:16 .he 99
:16 .he aa
:16 .he bb
:16 .he cc
:16 .he dd
:16 .he ee
:16 .he ff  ;-> 11 and ff is almost the same in PAL

PP´s of STARSOFTBerlin____github|meine Webseite|Demozoo

AntwortZitat

Tja, das sieht deutlich besser aus als der klassische Raster....toll gemacht PPS!

AntwortZitat